import React, { Component } from 'react'
import logo from './logo.png'
import './App.css'

import TodoList from './componsnts/TodoList'

// 函数组件 -> 无状态组件
/*function Some({ prop }) {
    return (
        <div>
            Something - {prop.toLocaleTimeString()}
        </div>
    )
} */

/*
    挂载
        constructor()
        static getDerivedStateFromProps() 
            render 之前调用, 它应返回一个对象来更新 state，如果返回 null 则不更新任何内容。
        render()
        componentDidMount()
    更新
        static getDerivedStateFromProps()
        shouldComponentUpdate()
        render()
        getSnapshotBeforeUpdate()
            DOM 更新前调用, 可以获取到一些DOM信息（例如，滚动位置）
            返回值可以传递给 componentDidUpdate()。
        componentDidUpdate()
    卸载
        componentWillUnmount()
*/

class Some extends React.Component {
    constructor(props) {
        super(props)
        console.log('1. 组件诞生')
        this.state = {
            count: 0
        }
    }
    
    static getDerivedStateFromProps() {
        // 在render调用之前, 应该返回一个对象来更新 state, 如果返回 null 则不更新任何内容
        console.log('2. 在render调用之前')
        return {count: 0}
    }

    componentDidMount() {
        console.log('3. 组件完成初始化')
    }
    
    shouldComponentUpdate() {
        // 是否要执行 render
        let n = Math.random() 
        console.log('4. 是否要执行 render', n)
        return true
    }

    getSnapshotBeforeUpdate() {
        console.log('4.5 已经允许更新 dom, 但未执行 render')
        return 'xxx'
    }

    componentDidUpdate(prevProps, provState, snapshot) {
        console.log('5. 组件 dom 已经更新完毕',)

        console.log(prevProps);
        console.log(provState);
        console.log(snapshot);

        console.log('------------');

    }

    componentWillUnmount() {
        console.log('6. 组件卸载')
    }

    handleClick = () => {
        this.setState({
            count: Math.random()
        })
    }

    render() {
        const { prop } = this.props
        return (
            <div>
                Something - {prop.toLocaleTimeString()}
                <button onClick={this.handleClick} >Btn</button>
            </div>
        )
    }
}

/*
    什么时候用函数组件, 什么时候用类组件
    有独立状态时, 用"类组件"
    仅展示内容时, 用"函数组件"
*/

// 类组件
export default class App extends Component {

    constructor(props) {
        super(props)
        this.state = {
            value: '',
            count: 0
        }
    }

    handleInput = (e) => {
        this.setState({
            value: e.target.value
        })
    }

    componentDidMount() {
        this.setState((prevState) => {
            return {
                count: 1
            }
        }, () => {
            console.log(this.state)
        })
    }

    getName = ({ firstName, lastName }) => {
        return `${firstName} - ${lastName}` 
    }

    SomeCallback = () => {
        console.log('this is parent')
    }

    render() {
        let jsx = <h1>jsx</h1>;
        let _html = `<h1>username</h1><p>Heelo </p>`;
        let f = true;
        let res = f && (<h3>Hello F</h3>);
        let arr = [1,2,3];
        return (
            <div>
                <TodoList />
                <hr />
                {/* 组件 */}
                <Some
                    prop={new Date()}
                    callback={this.SomeCallback}
                />
                {/* 列表渲染 */}
                <ul>
                    {
                        arr.map(item => <li key={item} >{item}</li> )
                    }
                </ul>
                {/* 条件渲染 */}
                {
                   f ? (<h3>Hello F</h3>) : null
                }
                {/* 组件状态 */}
                <input 
                    value={this.state.value}
                    onChange={this.handleInput}
                />
                {this.state.value}
                <br />
                Hello, App" 
                {/* 表达式 */}
                {jsx}
                {this.getName({ 
                    firstName: 'xinglong',
                    lastName: 'shi'
                })}
                {/* 属性 */}
                <img 
                    src={logo} 
                    style={{width: 100}} 
                    className='img'
                />
                <p dangerouslySetInnerHTML={{__html: _html}} ></p>
                
            </div>
        )
    }
}
